#pragma once
#define _CRT_SECURE_NO_WARNINGS 1
#include <iostream>
#include <assert.h>
using namespace std;
namespace A {

	class string
	{
	public:
		/*string()
		:_str(new char[1]{'\0'})
		  ,_size(0)
		  ,_capacity(0)
		  {}*/

		typedef char* iterator;
		typedef const char* const_iterator;
		  string(const char* str="") {
			  _size = strlen(str);
			   _str = new char[_size+1];
			   _capacity = _size;
			   strcpy(_str, str);

		  }

		  string(const string& s) {
			  _str = new char[s._capacity+1];
			  strcpy(_str,s._str);
			  _size = s._size;
			  _capacity = s._capacity;

		  }
		  ~string()
		  {
			  delete[] _str;
			  _str = nullptr;
			  _size = _capacity = 0;
		  }

		  string& operator=(const string& s) {
			 
			  if (this != &s) {
				  delete[] _str;
				  _str = new char[s._capacity + 1];
				  strcpy(_str, s._str);
				  _size = s._size;
				  _capacity = s._capacity;
				  
			  }
			  return *this;
		  }
		  const char* c_str()const {
			  return _str;
		  }
		  size_t size()const {
			  return _size;
		  }
		  size_t capacity()const {
			  return _capacity;
		  }
		  char& operator[](size_t pos) {
			  assert(pos < _size);
			  return _str[pos];
		  }

		  const char& operator[](size_t pos)const {
			  assert(pos < _size);
			  return _str[pos];
		  }
		  iterator begin() {
			  return _str;
		  }
		  const_iterator end()const {
			  return _str + _size;
		  }
		  const_iterator begin() const {
			  return _str;
		  }
		  iterator end() {
			  return _str + _size;
		  }
		  void push_back(char ch);
		  void append(const char* str);
		  string& operator+=(char ch);
		  string& operator+=(const char* str);
		  void reserve(size_t n);
		  void insert(size_t pos, char ch);
		  void insert(size_t pos, const char* str);
		  void erase(size_t pos, size_t len=npos);
		  size_t find(char ch, size_t pos = 0);
		  size_t find(const char* str, size_t pos = 0);
		  string substr(size_t pos = 0, size_t len = npos);
		  void clear();
	private:
		char* _str;
		size_t _size;
		size_t _capacity;
		static const  size_t npos;
	};

	//void test_string1();
	//void test_string2();
	bool operator<(const string& s1, const string& s2);
	bool operator<=(const string& s1, const string& s2);
	bool operator>(const string& s1, const string& s2);
	bool operator>=(const string& s1, const string& s2);
	bool operator==(const string& s1, const string& s2);
	bool operator!=(const string& s1, const string& s2);

	ostream& operator<<(ostream& out, const string& s);
	istream& operator>>(istream& in, string& s);

	

}
